package handlers

import (
	"bloggo/bloggo"
	"bloggo/dto"
	"bloggo/structs"
	"fmt"
	"gitee.com/chunanyong/zorm"
	"github.com/gin-gonic/gin"
	"strconv"
)

func init() {
	bloggo.AnonymousUrls = AnonymousUrls
	bloggo.UserResources = UserResources
}

// SendCode 发送验证码
func SendCode(c *gin.Context) *bloggo.R {
	username := c.DefaultQuery("username", "")
	if bloggo.SendMailCode(username) {
		return bloggo.Ok()
	}
	return bloggo.Fail()
}

// Register 注册
func Register(c *gin.Context) *bloggo.R {
	username := c.DefaultPostForm("username", "")
	password := c.DefaultPostForm("password", "")
	code := c.DefaultPostForm("code", "")
	r := bloggo.Register(username, password, code, bloggo.EMAIL)
	return r
}

// Login 登录
func Login(c *gin.Context) *bloggo.R {
	username := c.DefaultPostForm("username", "")
	password := c.DefaultPostForm("password", "")
	claims, token, err := bloggo.Login(username, password, bloggo.EMAIL, c.Request)
	if err != nil {
		return bloggo.FailMessage(err.Error())
	}
	var data dto.LoginDTO
	data.Claims = *claims
	data.Token = token

	finder := zorm.NewSelectFinder(structs.TbUserInfoStructTableName).Append("WHERE id=?", claims.UserId)
	userinfostruct := structs.TbUserInfoStruct{}
	_, err = zorm.QueryRow(c, finder, &userinfostruct)
	if err != nil || userinfostruct.IsDisable == 1 {
		panic("用户信息不存在!")
	}
	finder = zorm.NewSelectFinder(structs.TbUserAuthStructTableName).Append("WHERE user_info_id=?", claims.UserId)
	userAuthInfo := structs.TbUserAuthStruct{}
	_, err = zorm.QueryRow(c, finder, &userAuthInfo)
	if err != nil {
		panic("用户信息不存在!")
	}
	data.Avatar = userinfostruct.Avatar
	data.Email = userinfostruct.Email
	data.Id = userAuthInfo.Id
	data.Intro = userinfostruct.Intro
	data.IpAddress = userAuthInfo.IpAddress
	data.IpSource = userAuthInfo.IpSource
	data.LastLoginTime = userAuthInfo.LastLoginTime.String()
	data.LoginType = userAuthInfo.LoginType
	data.Nickname = userinfostruct.Nickname
	data.UserInfoId = userinfostruct.Id
	data.Username = userAuthInfo.Username
	data.WebSite = userinfostruct.WebSite

	smembers := bloggo.Smembers(fmt.Sprint(bloggo.ARTICLE_USER_LIKE, userinfostruct.Id))
	data.ArticleLikeSet = bloggo.BytessConvToInt(smembers)

	smembers = bloggo.Smembers(fmt.Sprint(bloggo.COMMENT_USER_LIKE, userinfostruct.Id))
	data.CommentLikeSet = bloggo.BytessConvToInt(smembers)
	return bloggo.OkData(data)
}

// QQLogin 扣扣登录
func QQLogin(c *gin.Context) *bloggo.R {
	return bloggo.QQLoginRedirect(c.Writer, c.Request)
}

// QQLoginRedirectTarget 扣扣登录重定向目标
func QQLoginRedirectTarget(c *gin.Context) *bloggo.R {
	claims, token, err := bloggo.QQLoginDefaultRedirectTarget(c.Request)
	if err != nil {
		return bloggo.FailMessage(err.Error())
	}
	var data dto.LoginDTO
	data.Claims = *claims
	data.Token = token

	finder := zorm.NewSelectFinder(structs.TbUserInfoStructTableName).Append("WHERE id=?", claims.UserId)
	userinfostruct := structs.TbUserInfoStruct{}
	_, err = zorm.QueryRow(c, finder, &userinfostruct)
	if err != nil || userinfostruct.IsDisable == 1 {
		panic("用户信息不存在!")
	}
	finder = zorm.NewSelectFinder(structs.TbUserAuthStructTableName).Append("WHERE user_info_id=?", claims.UserId)
	userAuthInfo := structs.TbUserAuthStruct{}
	_, err = zorm.QueryRow(c, finder, &userAuthInfo)
	if err != nil {
		panic("用户信息不存在!")
	}
	data.Avatar = userinfostruct.Avatar
	data.Email = userinfostruct.Email
	data.Id = userAuthInfo.Id
	data.Intro = userinfostruct.Intro
	data.IpAddress = userAuthInfo.IpAddress
	data.IpSource = userAuthInfo.IpSource
	data.LastLoginTime = userAuthInfo.LastLoginTime.String()
	data.LoginType = userAuthInfo.LoginType
	data.Nickname = userinfostruct.Nickname
	data.UserInfoId = userinfostruct.Id
	data.Username = userAuthInfo.Username
	data.WebSite = userinfostruct.WebSite

	smembers := bloggo.Smembers(fmt.Sprint(bloggo.ARTICLE_USER_LIKE, userinfostruct.Id))
	data.ArticleLikeSet = bloggo.BytessConvToInt(smembers)

	smembers = bloggo.Smembers(fmt.Sprint(bloggo.COMMENT_USER_LIKE, userinfostruct.Id))
	data.CommentLikeSet = bloggo.BytessConvToInt(smembers)
	return bloggo.OkData(data)
}

func About(c *gin.Context) *bloggo.R {
	//TODO 2022/11/17 关于我未实现
	return bloggo.OkData("")
}

// UserRoleIds 查询用户角色id
func UserRoleIds(ctx *gin.Context, userId string) (roleIds []string) {
	finder := zorm.NewFinder().Append("SELECT role_id FROM").Append(structs.TbUserRoleStructTableName)
	finder.Append("WHERE user_id=?", userId)
	err := zorm.Query(ctx, finder, &roleIds, nil)
	if err != nil {
		bloggo.Log(err.Error())
	}
	return roleIds
}

// UserResources 用户资源
func UserResources(ctx *gin.Context, userId string) (resList []bloggo.UserResource, err error) {
	//TODO 缓存
	finder := zorm.NewFinder().Append("SELECT role_id,resource_name,request_method,url,is_anonymous FROM")
	finder.Append(structs.TbRoleResourceStructTableName).Append("a").Append("LEFT JOIN")
	finder.Append(structs.TbResourceStructTableName).Append("b").Append("ON a.resource_id = b.id")
	finder.Append("WHERE role_id IN (?)", UserRoleIds(ctx, userId))
	err = zorm.Query(ctx, finder, &resList, nil)
	if err != nil {
		return resList, err
	}
	return resList, nil
}

// AnonymousUrls 可以匿名访问的url
func AnonymousUrls(ctx *gin.Context) (urls []bloggo.AnonymousUrl) {
	//TODO 缓存
	finder := zorm.NewFinder().Append("SELECT request_method,url FROM").Append(structs.TbResourceStructTableName)
	finder.Append("WHERE is_anonymous = ?", 1)
	_ = zorm.Query(ctx, finder, &urls, nil)
	return urls
}

// AdminUsers 管理用户列表
func AdminUsers(c *gin.Context) *bloggo.R {
	page := zorm.NewPage()
	page.PageNo, _ = strconv.Atoi(c.DefaultQuery("current", "1"))
	page.PageSize, _ = strconv.Atoi(c.DefaultQuery("size", "10"))
	keywords := c.DefaultQuery("keywords", "")
	loginType := c.DefaultQuery("loginType", "")
	finder := zorm.NewFinder().Append("SELECT a.id,a.user_info_id,b.avatar,b.nickname,a.login_type,a.ip_address,a.ip_source,a.create_time,a.last_login_time,b.is_disable")
	finder.Append("FROM").Append(structs.TbUserAuthStructTableName).Append("a")
	finder.Append("LEFT JOIN").Append(structs.TbUserInfoStructTableName).Append("b ON a.user_info_id=b.id")
	finder.Append("WHERE 1=1")
	if len(loginType) > 0 {
		finder.Append("AND a.login_type=?", loginType)
	}
	if len(keywords) > 0 {
		finder.Append("AND b.nickname LIKE ?", "%"+keywords+"%")
	}
	var data []dto.AdminUsers
	err := zorm.Query(c, finder, &data, page)
	if err != nil {
		return bloggo.FailMessage(err.Error())
	}
	if len(data) == 0 {
		return bloggo.OkData(gin.H{"recordList": nil, "count": 0})
	}
	for i := range data {
		f := zorm.NewFinder().Append("SELECT b.id,b.role_name FROM").Append(structs.TbUserRoleStructTableName)
		f.Append("a LEFT JOIN").Append(structs.TbRoleStructTableName).Append("b ON a.role_id=b.id")
		f.Append("WHERE user_id=?", data[i].UserInfoId)
		err = zorm.Query(c, f, &(data[i].RoleList), nil)
		if err != nil {
			return bloggo.FailMessage(err.Error())
		}
	}
	return bloggo.OkData(gin.H{"recordList": data, "count": page.TotalCount})
}
